﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SimpleSock
{
    public class SServer
    {
        public int Port { get; set; }
        public Action<string> DataArrived;
        public Func<string> Response;
        private Socket _socket;
        public SServer()
        {
        }

        public static SServer GetServer(int port, Action<string> dataArrived, Func<string> response)
        {
            var server = new SServer();
            server.Port = port;
            server.DataArrived += dataArrived;
            server.Response += response;
            server.Start();
            return server;
        }

        /// <summary>
        /// 使用默认端口 50100 创建服务器
        /// </summary>
        /// <param name="dataArrived"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        public static SServer GetServer(Action<string> dataArrived, Func<string> response)
        {
            return GetServer(50100, dataArrived, response);
        }

            public void Start()
        {
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _socket.Bind(new IPEndPoint(IPAddress.Any, Port));
            _socket.Listen(10);
            _socket.BeginAccept(new AsyncCallback(OnAccept), _socket);
        }

        private void OnAccept(IAsyncResult aresult)
        {
            try
            {
                Socket socket = aresult.AsyncState as Socket;
                Socket newClient = socket.EndAccept(aresult);
                socket.BeginAccept(new AsyncCallback(OnAccept), socket);
                byte[] recBuf = new byte[4096];
                int realRec = newClient.Receive(recBuf);
                string recvStr = Encoding.UTF8.GetString(recBuf, 0, realRec);
                if (DataArrived != null) DataArrived(recvStr);
                string s = "";
                if (Response != null) s = Response();
                newClient.Send(Encoding.UTF8.GetBytes(s));
                newClient.Close();

            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR!" + ex.Message);
            }
        }
    }
}
